package model;

import model.provider.RealMachineProvider;
import model.provider.VMMachineProvider;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import exception.InvalidHostNameException;
import exception.MachineInfoNotCompleteException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.ini4j.Wini;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author pyin
 */
@Singleton
public class MachineManager implements MM {

    private Wini cfg = null;
    public final String VM_CFG_FILE = "C:\\Documents and Settings\\dongxu\\My Documents\\NetBeansProjects\\test\\cfg\\machines.cfg";
    public final String VM_CFG_FILE_BACK = "C:\\Users\\think\\Documents\\NetBeansProjects\\test\\cfg\\machines.cfg";
    ConfigLoader configLoader;
//    TestScriptManager scriptManager;
//    ServerUtil serverUtil;
//    STAFHelper stafHelper;
    private VMMachineProvider vmProvider;
    private RealMachineProvider rmProvider;

    @Inject
    public MachineManager(ConfigLoader configLoader,
            ConfigManager configManager,
            //            TestScriptManager scriptManager,
            //            ServerUtil serverUtil,
            //            STAFHelper stafHelper,
            VMMachineProvider vmProvider,
            RealMachineProvider rmProvider) {
        this.configLoader = configLoader;
        this.vmProvider = vmProvider;
        this.rmProvider = rmProvider;
//        this.scriptManager = scriptManager;
//        this.serverUtil = serverUtil;
//        this.stafHelper = stafHelper;
    }

    private Wini getCfg() {
        cfg = configLoader.loadConfig(new File[]{new File(VM_CFG_FILE), new File(VM_CFG_FILE_BACK)});
//        if(cfg==null){
//            try {
//            cfg = new Wini(new File(ConfigManager.getVMMachineCfgFile()));
//        } catch (IOException ex) {
//            try {
//                cfg = new Wini(new File(VM_CFG_FILE_BACK));
//            } catch (IOException ex1) {
//                Logger.getLogger(MachineManager.class.getName()).log(Level.SEVERE, null, ex1);
//            }
//        }
//        }
        return cfg;
    }

    public boolean reload() {
        cfg = null;
        cfg = configLoader.loadConfig(new File[]{new File(VM_CFG_FILE), new File(VM_CFG_FILE_BACK)});
        return cfg == null ? false : true;
    }

//    static {
//        try {
//            cfg = new Wini(new File(ConfigManager.getVMMachineCfgFile()));
//            System.out.println("Loading from office dir.");
//        } catch (IOException ex) {
//            try {
//                cfg = new Wini(new File(VM_CFG_FILE_BACK));
//                System.out.println("Loading from home dir");
//                System.out.println(cfg.get("think-PC","SCRIPT_PATH"));
//            } catch (IOException ex1) {
//                Logger.getLogger(MachineManager.class.getName()).log(Level.SEVERE, null, ex1);
//            }
//        }
//    }
    public Machine getMachine(String name) throws InvalidHostNameException, MachineInfoNotCompleteException {
        if (isMachineValid(name)) {
            String vmHost = cfg.get(name, "VM_HOST");
            if (vmHost != null) {
                VMMachine machine = this.vmProvider.get();
//                VMMachine machine = new VMMachine(this.scriptManager, this.configManager, serverUtil, stafHelper);
//            VMMachine machine = Guice.createInjector().getInstance(VMMachine.class);
                machine.setName(name);
                machine.setOs(cfg.get(name, "OS"));
                machine.setVmFileName(cfg.get(name, "VM_FILE"));
                machine.setVmHost(cfg.get(name, "VM_HOST"));
                machine.setVmSnapShot(cfg.get(name, "VM_SNAPSHOT"));
                machine.setVmHost(cfg.get(name, "VM_HOST"));
                machine.setTsProjectPath(cfg.get(name, "SCRIPT_PATH"));
                machine.setTsProjectArchive(cfg.get(name, "SCRIPT_ARCHIVE"));
                machine.setInstallerPath(cfg.get(name, "INSTALLER_PATH"));
                machine.setTsTcPath(cfg.get(name, "SCRIPT_TC_PATH"));
                if (!machine.isInfoComplete()) {
                    throw new MachineInfoNotCompleteException();
                } else {
                    return machine;
                }
            } else {
                RealMachine machine = this.rmProvider.get();
//                RealMachine machine = new RealMachine();
                machine.setName(name);
                machine.setOs(cfg.get(name, "OS"));
                machine.setTsProjectPath(cfg.get(name, "SCRIPT_PATH"));
                machine.setTsProjectArchive(cfg.get(name, "SCRIPT_ARCHIVE"));
                machine.setInstallerPath(cfg.get(name, "INSTALLER_PATH"));
                machine.setTsTcPath(cfg.get(name, "SCRIPT_TC_PATH"));
                if (!machine.isInfoComplete()) {
                    throw new MachineInfoNotCompleteException();
                } else {
                    return machine;
                }
            }

        } else {
            throw new InvalidHostNameException();
        }

    }

    private boolean isMachineValid(String name) {
        try {
            FileReader fr = new FileReader(getCfg().getFile().getAbsolutePath());
            BufferedReader br = new BufferedReader(fr);
            String line;
            Pattern pattern = Pattern.compile("\\[([^\\[\\]]+)\\]");
            while ((line = br.readLine()) != null) {
                Matcher m = pattern.matcher(line);
                if (m.find()) {
                    if (m.group(1).equalsIgnoreCase(name)) {
                        return true;
                    }
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(MachineManager.class.getName()).log(Level.SEVERE, null, ex);
        }

//        System.out.println(result);
        return false;
    }

    public List getVMMachines()  {
        ArrayList result = new ArrayList();
        try {
            String vmCfgFile;
            if (new File(VM_CFG_FILE).exists()) {
                vmCfgFile = VM_CFG_FILE;
            } else {
                vmCfgFile = VM_CFG_FILE_BACK;
            }
            FileReader fr = new FileReader(vmCfgFile);
            BufferedReader br = new BufferedReader(fr);
            String line;
            Pattern pattern = Pattern.compile("\\[([^\\[\\]]+)\\]");
            while ((line = br.readLine()) != null) {
                Matcher m = pattern.matcher(line);
                if (m.find()) {
                    try {
                        result.add(getMachine(m.group(1)));
                    } catch (MachineInfoNotCompleteException ex) {
                        ;
                    }
                }
            }

        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        } catch (IOException ex) {
            Logger.getLogger(MachineManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidHostNameException e) {
        }
//        System.out.println(result);
        return result;
    }

//    public static void main(String[] args) {
//        try {
//            VMMachine machine = MachineManager.getMachine("think-pc");
//            System.out.println(machine.getOs());
//            System.out.println(machine.getVmFileName());
//            MachineManager.getVMMachines();
//        } catch (InvalidHostNameException ex) {
//            Logger.getLogger(MachineManager.class.getName()).log(Level.SEVERE, null, ex);
//        }
//    }
}
